package b3.net
{
	import b3.config.*;
	import b3.model.*;
	import b3.util.*;
	import b3.util.json.*;
	import b3.widget.basic.*;
	
	import flash.events.*;
	import flash.external.*;
	import flash.net.*;
	import flash.utils.*;
	
	public class ServerRequest
	{
		//动作
		public var action:String;
		//参数
		public var params:Object;
		//对话号
		public var sessionId:String;
		//呼叫号
		public var callId:int;
		//用户id
		public var userId:int;
		//上次呼叫号（互斥）
		private static var lastCallId:int;
		//请求URL
		private var postUrl:String;
		//回调函数
		private var handleFunc:Function;
		//同步时的服务器时间(单位：秒）
		private static var serverTime:int;
		//同步时的客户端时间（单位：秒）
		private static var clientTime:int;
		//时限（秒）
		private const processTimeOut:int = 10;
		//正在处理标志（互斥）
		private static var processingFlag:Boolean;	
		
		public function ServerRequest(action:String, params:Object = null)
		{
			this.action = action;
			this.params = params;
			this.postUrl = Profile.URL_Action;
		}
		
		public function post(force:Boolean = false):Boolean
		{
			var currentSeconds:int = currentSeconds(); 
			if (!force && processingFlag && currentSeconds - lastCallId < processTimeOut)
				return false;
			//准备参数
			var variables:URLVariables = new URLVariables();
			this.userId = PlayerManager.getInstance().myUserId;
			this.sessionId = PlayerManager.getInstance().sessionId;
			this.callId = currentSeconds > lastCallId ? currentSeconds : lastCallId + 1;
			var dataString:String = JSON.encode(this);
			dataString = utf8Encode(dataString);
			variables.json = escape(dataString);
			variables.b2Sig = generateSig(variables, Profile.serverSecret);
			//发送请求
			var request:URLRequest = new URLRequest(postUrl);
			request.method = URLRequestMethod.POST;
			request.data = variables;
			var loader:URLLoader = new URLLoader();
			loader.dataFormat = URLLoaderDataFormat.BINARY;
			loader.addEventListener(Event.COMPLETE, callBackFunc);
			loader.addEventListener(IOErrorEvent.IO_ERROR, handleIOError);
			try
			{
				processingFlag = true;
				lastCallId = callId;
				loader.load(request);
			}
			catch (error:Error)
			{
				processingFlag = false;
			}
			return processingFlag;
		}
		
		private function handleIOError(event:IOErrorEvent):void
		{
			processingFlag = false;
		}
		 
		//对中文进行UTF编码转化
		public static function utf8Encode(string:String):String 
		{
			string = string.replace(/\r\n/g,'\n');
			string = string.replace(/\r/g,'\n');
			
			var utfString:String = "";
			
			for (var i:int = 0 ; i < string.length ; i++) 
			{
				var chr:Number = string.charCodeAt(i);
				if (chr < 128) 
				{
					utfString += String.fromCharCode(chr);
				}
				else if ((chr > 127) && (chr < 2048)) 
				{
					utfString += String.fromCharCode((chr >> 6) | 192);
					utfString += String.fromCharCode((chr & 63) | 128);
				}
				else 
				{
					utfString += String.fromCharCode((chr >> 12) | 224);
					utfString += String.fromCharCode(((chr >> 6) & 63) | 128);
					utfString += String.fromCharCode((chr & 63) | 128);
				}
			}
			return utfString;
		}
		
		//生成指纹
		public static function generateSig(variables:URLVariables, secret:String):String
		{
			var varArray:Array = new Array();
			for (var key:String in variables)
			{
				varArray.push(key + "=" + variables[key]);
			} 
			varArray.sort();
			var varStr:String = varArray.join("");
			varStr += secret;
			varStr = utf8Encode(varStr);
			return Md5.hash(varStr);
		}
		
		private function callBackFunc(event:Event):void
		{
			DebugPane.getInstance().addInfo(event.target.data);
			var jsonObj:Object = JSON.decode(event.target.data);
			serverTime = jsonObj.timeStamp;
			clientTime = getTimer() / 1000;
			processingFlag = false;
			var response:ServerResponse = new ServerResponse();
			response.loadbyObject(jsonObj);
			if (response.res == 100 || response.res == 101)
			{
				ServerHelper.getInstance().dispatchEvent(new ServerEvent(ServerEvent.OTHER_LOGIN));
			}
			else
			{
				ServerHelper.getInstance().dispatchEvent(new ServerEvent(action));
				if (handleFunc != null)
				{
					handleFunc(response.data);
				}
			}
		}
		
		public function setHandleFunc(handleFunc:Function):void
		{
			this.handleFunc = handleFunc;
		}
		
		public function getHandleFunc():Function
		{
			return handleFunc;
		}
		
		public function setPostUrl(str:String):void
		{
			postUrl = str;
		}
		
		public function getPostUrl():String
		{
			return postUrl;
		}

		//模拟的当前的服务器系统时间(秒)
		public static function currentSeconds():int
		{
			return serverTime + getTimer() / 1000 - clientTime; 
		}
		
		//当前天数
		public static function currentDays():int
		{
			return currentSeconds() / 3600 / 24;
		}
		
		//好友分享
		public static function sendFeed(ongoingMessage:String, messageIndex:int = -1):void
		{
			if (messageIndex < 0 || messageIndex > Config.feedConfigs.length)
			{
				messageIndex = Math.random() * Config.feedConfigs.length; 
			}
			var feedConfig:FeedConfig = Config.feedConfigs[messageIndex];
			ExternalInterface.call("sendFeed", ongoingMessage, feedConfig.user_message, feedConfig.description, feedConfig.imgUrl);
		}
		
		//邀请好友
		public static function inviteFriend():void
		{
			ExternalInterface.call("sendRequest", true);
		}
		
		//重定向到游戏		
		public static function redirectToGamePage():void
		{
			ExternalInterface.call("window.open", Profile.URL_GAME_PAGE, "_parent");
		}
		
	}
}